home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
cli
/
mx2src.arc
/
XMODEM.MOD
< prev
next >
Wrap
Text File
|
1989-01-05
|
20KB
|
608 lines
(* Copyright 1987 fred brooks LogicTek *)
(* *)
(* *)
(* First Release 12/8/87-FGB *)
(* Minor fixups 3/7/88-FGB *)
(* *)
(*$T-,$S-,$A+ *)
(* This version of xmodem has been written using UNIX and the sealink
C programming versions as examples. Many thanks to those who have done
this before me. Fred Brooks *)
IMPLEMENTATION MODULE XMODEM;
FROM SYSTEM IMPORT ADDRESS, CODE, REGISTER, SETREG, ADR, WORD;
FROM GEMX IMPORT BasePageAddress, BasePageType ;
FROM BIOS IMPORT BConStat, BCosStat, BConIn, BConOut, Device;
FROM XBIOS IMPORT SuperExec;
FROM GEMDOS IMPORT Create, Open, Close, Write, Read, GetDTA, SFirst;
FROM TextIO IMPORT WriteString, WriteLn, WriteInt, WriteAdr;
FROM BitStuff IMPORT WAnd, WEor, WShl, WShr;
FROM Strings IMPORT String, Assign;
TYPE CharPtr = POINTER TO ARRAY [0..MAX(LONGINT)] OF CHAR;
CONST SECSIZ = 80H;
BUFSIZ = 200H;
ERRORMAX = 20;
RETRYMAX = 20;
SOH = 1c;
EOT = 4c;
ACK = 6c;
NAK = 25c;
C = 103c;
RTS = 4e75H;
BELL = 7c;
CTRLZ = 32c;
VAR result,mtimeout : INTEGER;
filename : String;
hz200 [04baH] : LONGCARD;
t1,prtime : LONGCARD;
readchar : CHAR;
filesize : POINTER TO LONGCARD;
snd,rec,ok : BOOLEAN;
(*$P- *)
PROCEDURE rdtime(); (* read 200hz clock *)
BEGIN
prtime:=hz200;
CODE(RTS);
END rdtime;
(*$P+ *)
PROCEDURE GetTime(): LONGCARD;
BEGIN
SuperExec(rdtime);
RETURN prtime;
END GetTime;
PROCEDURE timerset(time: INTEGER): LONGCARD;
BEGIN
RETURN (LONGCARD(time)+(GetTime() DIV 20));
END timerset;
PROCEDURE timeup(timer: LONGCARD): BOOLEAN;
BEGIN
IF ((GetTime() DIV 20)>timer) OR ((GetTime() DIV 20)=timer) THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END;
END timeup;
PROCEDURE errorbells;
VAR i,delay : CARDINAL;
BEGIN
FOR i:=0 TO 3 DO
FOR delay:=0 TO 10000 DO END;
BConOut(CON,BELL);
END;
END errorbells;
PROCEDURE crcupdate(crcvalue: CARDINAL; data: CHAR): CARDINAL;
CONST GEN1X5X12X16 = 1021H;
VAR i,xin,cha : INTEGER;
t : CARDINAL;
BEGIN
cha:=INTEGER(data);
FOR i:=0 TO 7 DO
xin:=INTEGER(WAnd(crcvalue,8000H));
cha:=INTEGER(WShl(cha,1));
IF INTEGER(WAnd(cha,100H))#0 THEN
t:=crcvalue;
crcvalue:=1+CARDINAL(WShl(t,1));
ELSE
t:=crcvalue;
crcvalue:=0+CARDINAL(WShl(t,1));
END;
IF xin#0 THEN
crcvalue:=CARDINAL(WEor(crcvalue,GEN1X5X12X16));
END;
END;
RETURN crcvalue;
END crcupdate;
PROCEDURE crcfinish(crcvalue: CARDINAL): CARDINAL;
BEGIN
RETURN CARDINAL(WAnd(crcupdate(crcupdate(crcvalue,0c),0c),0ffffH));
END crcfinish;
PROCEDURE IAnd255(num: INTEGER): INTEGER;
BEGIN
RETURN INTEGER(WAnd(num,0ffH));
END IAnd255;
PROCEDURE mdmini;
BEGIN
ok:=FALSE;
xmodemerror:=0;
xmodemabort:=FALSE;
mtimeout:=120;
mdmBytesXferred:=0;
mdmPacketsSent:=0;
mdmPacketsReceived:=0;
mdmBadPackets:=0;
mdmNakedPackets:=0;
END mdmini;
PROCEDURE xmodemstat;
BEGIN
WriteLn;
WriteString(" XMODEM STATUS ");
IF rec THEN
WriteString(" receiver active ");
WriteString(xfrname);
IF crcmode THEN
WriteString(" CRC mode.");
ELSE
WriteString(" CHECKSUM mode.");
END;
END;
IF snd THEN
WriteString(" transmitter active ");
WriteString(xfrname);
IF crcmode THEN
WriteString(" CRC mode.");
ELSE
WriteString(" CHECKSUM mode.");
END;
END;
WriteLn;
IF ok THEN
WriteString(" Transfer complete. ");
WriteLn;
END;
IF xmodemerror#0 THEN
WriteString(" Transfer aborted! ");
errorbells;
WriteLn;
END;
WriteLn;
WriteString(" Total packets sent ");
WriteInt(mdmPacketsSent,12);
WriteLn;
WriteString(" Packets left ");
WriteInt(endblk,12);
WriteLn;
WriteString(" Packets received ");
WriteInt(mdmPacketsReceived,12);
WriteLn;
WriteString(" Bad packets ");
WriteInt(mdmBadPackets,12);
WriteLn;
WriteString(" Naked packets sent ");
WriteInt(mdmNakedPackets,12);
WriteLn;
WriteString(" Bytes transferred ");
WriteAdr(ADDRESS(mdmBytesXferred),12);
WriteLn;
END xmodemstat;
PROCEDURE setbuffer(char: CharPtr; length: CARDINAL; value: CHAR);
VAR data : POINTER TO CHAR;
BEGIN
WHILE length#0 DO
data:=ADDRESS(char);
data^:=value;
INC(char);
DEC(length);
END;
END setbuffer;
PROCEDURE writeModem(char: CharPtr; count: LONGCARD);
VAR data : POINTER TO CHAR;
BEGIN
WHILE count#0 DO
DEC(count);
data:=ADDRESS(char);
INC(char);
sendchar(data^);
END;
END writeModem;
PROCEDURE readModem(VAR char: CHAR; time: INTEGER);
VAR data : CHAR;
longchar : LONGCARD;
t : BITSET;
WaitTime : LONGCARD;
ticks : CARDINAL;
BEGIN
IF time=0 THEN
IF BConStat(AUX) THEN (* return char *)
longchar:=BConIn(AUX);
t:=BITSET(longchar);
EXCL(t,8);
char:=CHAR(t);
RETURN;
ELSE
char:=CHAR(255);
RETURN;
END;
END;
WaitTime:=LONGCARD(time)+(GetTime() DIV 20);
ticks:=0;
LOOP
IF BConStat(AUX) THEN
longchar:=BConIn(AUX);
t:=BITSET(longchar);
EXCL(t,8);
char:=CHAR(t);
RETURN;
END;
IF ((GetTime() DIV 20)>WaitTime)
OR ((GetTime() DIV 20)=WaitTime) THEN
INC(ticks);
WaitTime:=LONGCARD(time)+(GetTime() DIV 20);
IF ticks=2 THEN
char:=CHAR(255);
RETURN;
END;
END;
END; (* loop *)
END readModem;
PROCEDURE flushinput();
VAR char : LONGCARD;
BEGIN
WHILE BConStat(AUX) DO
char:=BConIn(AUX);
END;
END flushinput;
PROCEDURE sendchar(char: CHAR);
BEGIN
BConOut(AUX,char);
END sendchar;
PROCEDURE xmodemrec(filename: ARRAY OF CHAR): BOOLEAN;
VAR sectnum,s